 
 
import { StationNetwork } from "GameLoop/Path/StationNetwork";
import { adjacent_dirs, fill_structure } from "utils/constants/moveConstant";
import { CreepAbilityHelper } from "utils/creep/CreepAbilityHelper";
import { cache_return } from "utils/decorate/decorate";
import { UtilsHelper } from "utils/position/UtilsHelper";
export enum EBoostState
{
    Renew=1,
    Boost=2,
}
/**
 * 在跨房间移动的时候撞墙了。这时候就会在边界左右横跳。
 * 所以在从出口到出口移动的时候禁止寻路
 */

export default class CreepExtension extends Creep
{
    private _aroundHostileCreeps?:Creep[]
    public nextpos!:RoomPosition;   // 预期的下一个位置坐标，用来计算承受伤害
    private _ability_heal?:number;
    private _msg_cache?:string;     // 
    public getAbilityHeal():number
    {
        if(!this._ability_heal)
        {
            this._ability_heal = CreepAbilityHelper.getCreepHealAbility(this);
        }
        return this._ability_heal;
    }
    public heal(target: AnyCreep): CreepActionReturnCode
    {
        if(!target|| !target.pos)
        {
            return ERR_INVALID_TARGET;
        }
        if(target.pos.distance(this.pos)>1)
        {
            return this.rangedHeal(target);
        }
        return this._heal(target);
    }
    public withdraw(target: Structure | Tombstone | Ruin|Creep, resourceType: ResourceConstant, amount?: number): ScreepsReturnCode
    {
        if(target.getType() == "Creep")
        {
            return (target as Creep).transfer(this,resourceType,amount)
        }
        else 
        {
            if(!this._withdraw)
            {
                global.Log.Error(`${this.getType()} ${JSON.stringify(this.pos)}`);
                return ERR_INVALID_TARGET
            }
            return this._withdraw(target as any,resourceType,amount);
        }
    }
    public say(message: string, toPublic?: boolean): OK | ERR_NOT_OWNER | ERR_BUSY 
    {
        if(!this._msg_cache)
        {
            this._msg_cache = message;
        }
        else 
        {
            return ERR_BUSY
        }
        return this._say(message, toPublic);
    }
    /**
     * 治疗周围的爬
     * @returns 
     */
    public healAroundCreep()
    {
        const hurtcreeps  = _.min(this.room.getHurtCreeps(),e=>e.pos.distance(this.pos));
        if(hurtcreeps&& hurtcreeps.pos)
        {
            if(hurtcreeps.pos.inRangeTo(this.pos,1))
            {
                this.heal(hurtcreeps);
                return true
            }
            else if(hurtcreeps.pos.inRangeTo(this.pos,3))
            {
                this.rangedHeal(hurtcreeps);
                return true
            }
        }
        return false;
    }

    /**
     * 修理爬脚下的 路
     */
    public repairFoot()
    {
        if(this.getNodeMemory().body[WORK])
        {
            const cache = this.room.getWorld().PollStructure(this.room.name);
            if(cache)
            {
                const stucture =Game.getObjectById( cache.lookStructure(STRUCTURE_ROAD,this.pos)?.id as Id<StructureRoad>);
                if(stucture  )
                {
                    if(stucture.hits<stucture.hitsMax*0.9)
                    {
                        this.repair(stucture);
                        return true;
                    }
                    else 
                    {
                        // this.log(`warn`,` ${cache.lookStructure(STRUCTURE_ROAD,this.pos)?.id } 耐久已经足够`)
                    }
                }
                else 
                {
                    //this.log(`warn`,`${JSON.stringify(this.pos)} 找不到建筑对象`)
                }
            }
            else 
            {
                 //this.log(`warn`,`找不到建筑缓存`)
            }
        }
        else 
        {
            //this.log(`warn`,`没有work`)
        }
        return false
    }
    public buildFoot()
    {
        if(this.getNodeMemory().body[WORK])
        {
            const cache = this.room.getWorld().PollConstructSites(this.room.name);
            if(cache)
            {
                const site = this.pos.lookFor(LOOK_CONSTRUCTION_SITES) ;
                if(site&& site.length  )
                {
                    this.build(site[0]);
                    return true;
                }
            }
        }
        return false
    }
    public setAroundHostileCreeps(creeps:Creep[])
    {
        if(this._aroundHostileCreeps)
        {
            this._aroundHostileCreeps = this._aroundHostileCreeps.concat(creeps);
        }
        else 
        {
            this._aroundHostileCreeps = creeps;
        }
        
    }

    public getAroundHostileCreeps():Creep[]
    {
        return this._aroundHostileCreeps?this._aroundHostileCreeps:[];
    }

    public bodyCount(body:BodyPartConstant)
    {
        return this.memory.body[body]?this.memory.body[body]:0
    }

    /**
     * 
     * @param direction 前进方向
     * 填充前进方向的对象
     */
    public fillFroword(direction:DirectionConstant,filter:(s:Structure)=>boolean=(e:Structure)=>{
        return fill_structure.has(e.structureType) &&(e as AnyStoreStructure).store && (e as AnyStoreStructure).store.getFreeCapacity(RESOURCE_ENERGY)>0
    })
    {
        const dirs = adjacent_dirs[direction]? adjacent_dirs[direction]:adjacent_dirs[0];
         
         
        const pos = this.pos;
        for(const e of dirs)
        {
            const offset = UtilsHelper.getOffset(e);
            const nxtpos = {x:pos.x+offset[0],y:pos.y+offset[1]} ;
            if(nxtpos.x<0 || nxtpos.x>=50 || nxtpos.y<0 || nxtpos.y>=50)
            {
                continue;
            }
            const objects = this.room.lookForAt(LOOK_STRUCTURES,nxtpos.x,nxtpos.y).filter(filter);
            if(objects.length)
            {
                return this.transfer(objects[0],RESOURCE_ENERGY);
            }
        }
        
        return ERR_NOT_FOUND
    }
    /**
     * 当前爬的角色
    */
    public   ActiveRole()
    {
        return this.memory?.Role;
    }

    public isSpawned():boolean
    {
        if( this.ticksToLive && this.ticksToLive != 1500 &&!this.spawning  )
        {
            return true;
        }
        
        return false;
    }
    /**
     * 判断爬是否已经准备就绪。已经boost了
     * @returns 
     */
    public isBoostComplete()
    {
        if(this.memory.BoostLevel && !this.memory.IsBoosted)
        {
            return false;
        }
        return true;
    }

    @cache_return("crossLevel",0)
    public crossLevel():number
    {
        if(this.memory.taskid || this.memory.teamid || this.memory.state || this.memory.Role == "manager"||  this.memory.Role == "filler" )
        {
            return this.memory.crossLevel;
        }
        return 0
    }
}
